/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License, Version 1.0 only
 * (the "License").  You may not use this file except in compliance
 * with the License.
 *
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 * or http://www.opensolaris.org/os/licensing.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information: Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 */
/*
 * Key server protocol definition
 * Copyright (C) 1990, 1991 Sun Microsystems, Inc.
 *
 * The keyserver is a public key storage/encryption/decryption service
 * The encryption method used is based on the Diffie-Hellman exponential
 * key exchange technology.
 *
 * The key server is local to each machine, akin to the portmapper.
 * Under TI-RPC, communication with the keyserver is through the
 * loopback transport.
 *
 * NOTE: This .x file generates the USER level headers for the keyserver.
 * the KERNEL level headers are created by hand as they kernel has special
 * requirements.
 */

%
%/* Copyright (c)  1990, 1991 Sun Microsystems, Inc. */
%
%/*
% * Compiled from key_prot.x using rpcgen.
% * DO NOT EDIT THIS FILE!
% * This is NOT source code!
% */

/*
 * PROOT and MODULUS define the way the Diffie-Hellman key is generated.
 *
 * MODULUS should be chosen as a prime of the form: MODULUS == 2*p + 1,
 * where p is also prime.
 *
 * PROOT satisfies the following two conditions:
 * (1) (PROOT ** 2) % MODULUS != 1
 * (2) (PROOT ** p) % MODULUS != 1
 *
 */

const PROOT = 3;
const HEXMODULUS = "d4a0ba0250b6fd2ec626e7efd637df76c716e22d0944b88b";

const HEXKEYBYTES = 48;		/* HEXKEYBYTES == strlen(HEXMODULUS) */
const KEYSIZE = 192;		/* KEYSIZE == bit length of key */
const KEYBYTES = 24;		/* byte length of key */

/*
 * The first 16 hex digits of the encrypted secret key are used as
 * a checksum in the database.
 */
const KEYCHECKSUMSIZE = 16;

/*
 * status of operation
 */
enum keystatus {
	KEY_SUCCESS,	/* no problems */
	KEY_NOSECRET,	/* no secret key stored */
	KEY_UNKNOWN,	/* unknown netname */
	KEY_SYSTEMERR, 	/* system error (out of memory, encryption failure) */
	KEY_BADALG,	/* unknown algorithm type */
	KEY_BADLEN	/* unsupported keysize */
};

typedef opaque keybuf[HEXKEYBYTES];	/* store key in hex */
typedef opaque keybuf3<>;		/* store key in binary */

typedef string netnamestr<MAXNETNAMELEN>;

/*
 * algorithm type & key size
 */
typedef int keylen_t;
typedef int algtype_t;

struct mechtype {
	keylen_t keylen;
	algtype_t algtype;
};

/*
 * number of keys for KEY_GEN_3 to return
 */
typedef int keynum_t;

/*
 * Result of KEY_GEN_3
 */
typedef des_block deskeyarray<>;

/*
 * Argument to ENCRYPT or DECRYPT
 */
struct cryptkeyarg {
	netnamestr remotename;
	des_block deskey;
};

/*
 * Argument to ENCRYPT_PK or DECRYPT_PK
 */
struct cryptkeyarg2 {
	netnamestr remotename;
	netobj	remotekey;	/* Contains a length up to 1024 bytes */
	des_block deskey;
};

/*
 * Argument to ENCRYPT_3, ENCRYPT_PK_3, DECRYPT_3, DECRYPT_PK_3
 */
struct cryptkeyarg3 {
	netnamestr remotename;
	keybuf3 remotekey;
	deskeyarray deskey;
	algtype_t algtype;
	keylen_t keylen;
};

/*
 * Result of ENCRYPT, DECRYPT, ENCRYPT_PK, DECRYPT_PK, KEY_GET_CONV
 */
union cryptkeyres switch (keystatus status) {
case KEY_SUCCESS:
	des_block deskey;
default:
	void;
};

/*
 * Result of ENCRYPT_3, DECRYPT_3, ENCRYPT_PK_3, DECRYPT_PK_3, KEY_GET_CONV_3
 */
union cryptkeyres3 switch (keystatus status) {
case KEY_SUCCESS:
	deskeyarray deskey;
default:
	void;
};

const MAXGIDS  = 16;	/* max number of gids in gid list */

/*
 * Unix credential
 */
struct unixcred {
	u_int uid;
	u_int gid;
	u_int gids<MAXGIDS>;
};

/*
 * Unix credential, without arbitrary limit
 */
struct unixcred3 {
	u_int uid;
	u_int gid;
	u_int gids<>;
};

/*
 * Result returned from GETCRED
 */
union getcredres switch (keystatus status) {
case KEY_SUCCESS:
	unixcred cred;
default:
	void;
};

/*
 * Result returned from GETCRED_3
 */
union getcredres3 switch (keystatus status) {
case KEY_SUCCESS:
	unixcred3 cred;
default:
	void;
};

/*
 * key_netstarg;
 */
struct key_netstarg {
	keybuf st_priv_key;
	keybuf st_pub_key;
	netnamestr st_netname;
};

struct key_netstarg3 {
	keybuf3 st_priv_key;
	keybuf3 st_pub_key;
	netnamestr st_netname;
	algtype_t algtype;
	keylen_t keylen;
	des_block userkey;
};

union key_netstres switch (keystatus status){
case KEY_SUCCESS:
	key_netstarg knet;
default:
	void;
};

union key_netstres3 switch (keystatus status){
case KEY_SUCCESS:
	key_netstarg3 knet;
default:
	void;
};

/*
 * Argument to KEY_GET_CONV_3
 */
struct deskeyarg3 {
	keybuf3 pub_key;
	int nkeys;
	algtype_t algtype ;
	keylen_t keylen;
};

/*
 * Argument to KEY_SET_3
 */
struct setkeyarg3 {
	keybuf3 key;
	des_block userkey;
	algtype_t algtype ;
	keylen_t keylen;
};

#ifdef RPC_HDR
%
%#ifndef opaque
%#define	opaque char
%#endif
%
#endif
program KEY_PROG {
	version KEY_VERS {

		/*
		 * This is my secret key.
	 	 * Store it for me.
		 */
		keystatus
		KEY_SET(keybuf) = 1;

		/*
		 * I want to talk to X.
		 * Encrypt a conversation key for me.
	 	 */
		cryptkeyres
		KEY_ENCRYPT(cryptkeyarg) = 2;

		/*
		 * X just sent me a message.
		 * Decrypt the conversation key for me.
		 */
		cryptkeyres
		KEY_DECRYPT(cryptkeyarg) = 3;

		/*
		 * Generate a secure conversation key for me
		 */
		des_block
		KEY_GEN(void) = 4;

		/*
		 * Get me the uid, gid and group-access-list associated
		 * with this netname (for kernel which cannot use NIS)
		 */
		getcredres
		KEY_GETCRED(netnamestr) = 5;
	} = 1;
	version KEY_VERS2 {

		/*
		 * #######
		 * Procedures 1-5 are identical to version 1
		 * #######
		 */

		/*
		 * This is my secret key.
	 	 * Store it for me.
		 */
		keystatus
		KEY_SET(keybuf) = 1;

		/*
		 * I want to talk to X.
		 * Encrypt a conversation key for me.
	 	 */
		cryptkeyres
		KEY_ENCRYPT(cryptkeyarg) = 2;

		/*
		 * X just sent me a message.
		 * Decrypt the conversation key for me.
		 */
		cryptkeyres
		KEY_DECRYPT(cryptkeyarg) = 3;

		/*
		 * Generate a secure conversation key for me
		 */
		des_block
		KEY_GEN(void) = 4;

		/*
		 * Get me the uid, gid and group-access-list associated
		 * with this netname (for kernel which cannot use NIS)
		 */
		getcredres
		KEY_GETCRED(netnamestr) = 5;

		/*
		 * I want to talk to X. and I know X's public key
		 * Encrypt a conversation key for me.
	 	 */
		cryptkeyres
		KEY_ENCRYPT_PK(cryptkeyarg2) = 6;

		/*
		 * X just sent me a message. and I know X's public key
		 * Decrypt the conversation key for me.
		 */
		cryptkeyres
		KEY_DECRYPT_PK(cryptkeyarg2) = 7;

		/*
		 * Store my public key, netname and private key.
		 */
		keystatus
		KEY_NET_PUT(key_netstarg) = 8;

		/*
		 * Retrieve my public key, netname and private key.
		 */
 		key_netstres
		KEY_NET_GET(void) = 9;

		/*
		 * Return me the conversation (common) key that is constructed
		 * from my secret key and this publickey.
		 */
		cryptkeyres
		KEY_GET_CONV(keybuf) = 10;
	} = 2;
	version KEY_VERS3 {

		/*
		 * #######
		 * Procedures 1-10 are identical to versions 1 & 2
		 * #######
		 */

		/*
		 * This is my secret key.
	 	 * Store it for me.
		 */
		keystatus
		KEY_SET(keybuf) = 1;

		/*
		 * I want to talk to X.
		 * Encrypt a conversation key for me.
	 	 */
		cryptkeyres
		KEY_ENCRYPT(cryptkeyarg) = 2;

		/*
		 * X just sent me a message.
		 * Decrypt the conversation key for me.
		 */
		cryptkeyres
		KEY_DECRYPT(cryptkeyarg) = 3;

		/*
		 * Generate a secure conversation key for me
		 */
		des_block
		KEY_GEN(void) = 4;

		/*
		 * Get me the uid, gid and group-access-list associated
		 * with this netname (for kernel which cannot use NIS)
		 */
		getcredres
		KEY_GETCRED(netnamestr) = 5;

		/*
		 * I want to talk to X. and I know X's public key
		 * Encrypt a conversation key for me.
	 	 */
		cryptkeyres
		KEY_ENCRYPT_PK(cryptkeyarg2) = 6;

		/*
		 * X just sent me a message. and I know X's public key
		 * Decrypt the conversation key for me.
		 */
		cryptkeyres
		KEY_DECRYPT_PK(cryptkeyarg2) = 7;

		/*
		 * Store my public key, netname and private key.
		 */
		keystatus
		KEY_NET_PUT(key_netstarg) = 8;

		/*
		 * Retrieve my public key, netname and private key.
		 */
 		key_netstres
		KEY_NET_GET(void) = 9;

		/*
		 * Return me the conversation (common) key that is constructed
		 * from my secret key and this publickey.
		 */
		cryptkeyres
		KEY_GET_CONV(keybuf) = 10;

		/*
		 * #######
		 * Procedures new in version 3 follow...
		 * #######
		 */

		/*
		 * This is my secret key.
	 	 * Store it for me.
		 */
		keystatus
		KEY_SET_3(setkeyarg3) = 11;

		/*
		 * I want to talk to X.
		 * Encrypt a conversation key for me.
	 	 */
		cryptkeyres3
		KEY_ENCRYPT_3(cryptkeyarg3) = 12;

		/*
		 * X just sent me a message.
		 * Decrypt the conversation key for me.
		 */
		cryptkeyres3
		KEY_DECRYPT_3(cryptkeyarg3) = 13;

		/*
		 * Generate secure conversation key(s) for me
		 */
		deskeyarray
		KEY_GEN_3(keynum_t) = 14;

		/*
		 * Get me the uid, gid and group-access-list associated
		 * with this netname (for kernel which cannot use NIS)
		 */
		getcredres3
		KEY_GETCRED_3(netnamestr) = 15;

		/*
		 * I want to talk to X. and I know X's public key
		 * Encrypt a conversation key for me.
	 	 */
		cryptkeyres3
		KEY_ENCRYPT_PK_3(cryptkeyarg3) = 16;

		/*
		 * X just sent me a message. and I know X's public key
		 * Decrypt the conversation key for me.
		 */
		cryptkeyres3
		KEY_DECRYPT_PK_3(cryptkeyarg3) = 17;

		/*
		 * Store my public key, netname and private key.
		 */
		keystatus
		KEY_NET_PUT_3(key_netstarg3) = 18;

		/*
		 * Retrieve my public key, netname and private key.
		 */
 		key_netstres3
		KEY_NET_GET_3(key_netstarg3) = 19;

		/*
		 * Return me the conversation (common) key that is constructed
		 * from my secret key and this publickey.
		 */
		cryptkeyres3
		KEY_GET_CONV_3(deskeyarg3) = 20;

		/*
		 * Clear all the secret/public/netname triplets for the caller
		 */
		keystatus
		KEY_CLEAR_3(void) = 21;

	} = 3;
} = 100029;
